﻿#pragma once
#include <vector>
#include <iostream>

const double CountMinValue = 1e-4;											// 各种单位化后的计算的最小值1e-4
const double MapMinValue = 0.5 + 1e-3;										// 各种和地图的值有关的最小值 1 + 1e-3
const double DoubleMaxNumValue = std::numeric_limits<double>::max();		// double 计算的最大值
const double PI = 3.14159265358979323846;									// Pi
const double PE = PI / 180.0f;												// 角度转弧度 角度乘PE可得弧度值
const int PCIBoost = 1000;													// boost 外扩时用来放大的倍数
const double AngleMaxValue = 8 * 1e-4;										// 角度差值的最大误差0.008(8 * 1e-3),对应0.5度


class Point {
public:
	Point() {
		this->x = 0;
		this->y = 0;
	}

	Point(double x, double y) {
		this->x = x;
		this->y = y;
	}

	//一般要锁住才调这个 LockPoint = true
	Point(double x, double y, bool LockPoint) {
		this->x = x;
		this->y = y;
		this->locked = LockPoint;
	}


public:

	void setLocked(bool Lock) {
		this->locked = Lock;
	}
	bool getLocked() const {
		return this->locked;
	}
	double distanceTo(const Point& other) const {
		return sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y));
	}

	Point operator*(double k) const {
		return { x * k , y * k };
	}

	Point operator/(double k) const {
		return { x / k , y / k };
	}

	Point operator+(Point a) const {
		return { x + a.x , y + a.y };
	}

	Point operator-(const Point& other) const {
		return Point(x - other.x, y - other.y);
	}

	double operator*(Point a) const {
		return x * a.x + y * a.y;
	}

	Point operator/(Point a) const {
		return { x / a.x , y / a.y };
	}

	// 添加小于运算符的定义
	bool operator<(const Point& other) const {
		return (x < other.x) || (x == other.x && y < other.y);
	}

	bool operator==(Point p) const
	{
		return (abs(x - p.x) < CountMinValue && abs(y - p.y) < CountMinValue);
	}

	bool operator!=(Point p) const
	{
		return (fabs(x - p.x) > CountMinValue || fabs(y - p.y) > CountMinValue);
	}

	Point normalizeVec()const {    //取单位向量

		return (*this / sqrt(this->x * this->x + this->y * this->y));
	}

	double vecLength()const {      //取向量的模长
		return sqrt(this->x * this->x + this->y * this->y);
	}

	friend std::ostream& operator<<(std::ostream& print, const Point& p) {
		print << "(" << p.x << "," << p.y << ")";
		return print;
	}

public:
	double x;
	double y;
	bool locked = false;  //当前点是否固定 :[1] locked = false: 不固定；[2] locked = true: 固定 ----默认不固定
private:
	double minNumber = 0.0001;

};

class Line {  // class _declspec(dllexport)Line {
public:
	Line() {}
	Line(Point sP_, Point eP_, Point mP_);
	Line(Point sP_, Point eP_);
	Line(Point circlePoint, double circleRadius);

	double cross(Point a, Point b)const;
	Point rotate(Point vec, double angle);
	double norm(Point a);
	Point getCrossingPoint(Line& otherLine)const;
	//Point getInsection(Point Vec1, Point p1, Point Vec2, Point p2);
	void getCenterP(Line line);
	Point getVector()const;
	double getLength()const;

	bool operator==(Line line1) const;
	// 对起点的操作
	Point& getPt1() {
		return this->Pt1;
	}

	const Point& getPt1() const {
		return this->Pt1;
	}

	void setPt1(const Point& pt1) {
		Line::Pt1 = pt1;
	}

	// 对终点的操作
	Point& getPt2() {
		return this->Pt2;
	}

	const Point& getPt2() const {
		return this->Pt2;
	}

	void setPt2(const Point& pt2) {
		Line::Pt2 = pt2;
	}
	// 对圆弧的中点的操作
	Point& getarcP() {
		return this->arcP;
	}

	void setarcP(const Point& arcP) {
		Line::arcP = arcP;
	}


	double& getRadius() {
		return this->Radius;
	}

	int& getState() {
		return this->State;
	}

	void setState(const int& state) {
		Line::State = state;
	}

public:
	friend std::ostream& operator<<(std::ostream& print, const Line& straightLine) {
		print << "The properties of the Line are:\n";
		print << "Origin Point:" << straightLine.Pt1 << "\n";
		print << "Terminal Point:" << straightLine.Pt2 << "\n";
		if (straightLine.State == 1) {
			print << "Arc Point:" << straightLine.arcP << "\n";
			print << "circleCenter Point:" << straightLine.circleCenter << "\n";
			print << "Radius:" << straightLine.Radius << "\n";
		}
		return print;
	}

public:
	Point Pt1;  //起点
	Point Pt2;  // 终点
	int layer = 0;
	Point arcP;  //圆弧的中点
	Point circleCenter;   //圆心
	double Radius = 0;       //半径
	int State = 0;      // State = 0：segLine; State = 1: arcLine  notice: default = 0; State == 2: Circle
	double width = 0;

};


